package com.gtw.modules.api.controller;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.jssdk.JSSDKAPI;
import com.foxinmy.weixin4j.jssdk.JSSDKConfigurator;
import com.foxinmy.weixin4j.mp.WeixinProxy;
import com.foxinmy.weixin4j.mp.model.User;
import com.foxinmy.weixin4j.token.TokenManager;
import com.foxinmy.weixin4j.type.TicketType;
import com.gtw.common.annotation.AuthIgnoreApi;
import com.gtw.common.utils.R;
import com.gtw.common.utils.WeiXinMsgUtil;
import com.gtw.modules.api.service.TbTokenService;
import com.gtw.modules.api.service.TbUserService;
import com.gtw.modules.entity.TbDataInfo;
import com.gtw.modules.entity.TbUser;
import com.gtw.modules.entity.WxAutoSayEntity;
import com.gtw.modules.sys.service.SysDataInfoService;
import com.gtw.modules.sys.service.WxAutoSayService;
import com.gtw.modules.wx.AdvancedUtil;
import com.gtw.modules.wx.CommonUtil;
import com.gtw.modules.wx.MessageUtil;
import com.gtw.modules.wx.SNSUserInfo;
import net.sf.json.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Date;
import java.util.Map;

/**
 * 微信token验证
 * 开发者自定的验证口令
 */
@RestController
@RequestMapping("/api/wx")
public class weixinController {
    private Logger logger = LoggerFactory.getLogger(weixinController.class);

    @Autowired
    private TbUserService tbUserService;

    @Autowired
    private SysDataInfoService sysDataInfoService;

    @Autowired
    private TbTokenService tbTokenService;
    @Autowired
    private WeixinProxy weixinProxy;
    @Autowired
    private WxAutoSayService wxAutoSayService;

    @AuthIgnoreApi
    @RequestMapping(value = "/checkToken", method = RequestMethod.GET)
    public String check(String signature, String timestamp, String nonce, String echostr) {
        // TODO: 2018/8/8 验证消息的有效性 微信服务器
        return echostr;
    }


    @AuthIgnoreApi
    @RequestMapping(value = "/checkToken", method = RequestMethod.POST)
    public String check(@RequestBody(required = false) String body) throws IOException {
        //推送消息给用户
        logger.info("body:" + body);
        // xml请求解析
        Map<String, String> requestMap = MessageUtil.parseXmlToMap2(body);
        logger.info("xml的消息:" + requestMap);
        // 开发者（open_id）
        String fromUserName = requestMap.get("FromUserName");

        // 接收方帐号（收到的OpenID）
        String toUserName = requestMap.get("ToUserName");

        // 消息类型
        String msgType = requestMap.get("MsgType");

        // 消息内容
        String content = requestMap.get("Content");

        // 事件推送
        if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_EVENT)) {
            String eventType = requestMap.get("Event");// 事件类型
            // 扫描带参数二维码
            //关注公众号事件
            if (eventType.equals(MessageUtil.EVENT_TYPE_SCAN) || eventType.equals(MessageUtil.EVENT_TYPE_SUBSCRIBE)) {
                logger.info("扫描带参数二维码事件以及关注事件:");
                //
                WxAutoSayEntity wxAutoSayEntity = wxAutoSayService.queryObject(1);
                String rcontent = "";//回复内容
                if (wxAutoSayEntity != null) {
                    rcontent = wxAutoSayEntity.getContent();
                }
                StringBuffer str = new StringBuffer();
                str.append("<xml>");
                str.append("<ToUserName><![CDATA[" + fromUserName + "]]></ToUserName>");
                str.append("<FromUserName><![CDATA[" + toUserName + "]]></FromUserName>");
                str.append("<CreateTime>" + new Date() + "</CreateTime>");
                str.append("<MsgType><![CDATA[" + "text" + "]]></MsgType>");
                str.append("<Content><![CDATA[" + rcontent + "]]></Content>");
                str.append("</xml>");

                new Thread(() -> {
                    String eventKey = requestMap.get("EventKey");
                    if (StringUtils.isBlank(eventKey)) return;
                    String userIdStr = eventKey.replace("qrscene_", "");
                    int pid = Integer.valueOf(userIdStr);
                    TbUser tbUser = tbUserService.queryOpenId(fromUserName);
                    TbUser parent = tbUserService.queryById(pid);

                    if (tbUser == null) {
                        // 获取用户信息
                        try {
                            User weixinProxyUser = weixinProxy.getUser(fromUserName);
                            //未注册，注册
                            tbUser = new TbUser(weixinProxyUser);
                            TbDataInfo tbDataInfo = sysDataInfoService.queryObject(1);
                            tbUser.setWithdrawaltimes(tbDataInfo.getDate());

                            if (parent == null || parent.getType() == 0) {
                                tbUser.setParentid(1);
                                tbUserService.add(tbUser);
                            } else {
                                bindParend(tbUser, parent);
                                tbUserService.add(tbUser);
                            }
                        } catch (WeixinException e) {
                            logger.error("拉取微信用户信息失败",e);
                        }
                    } else if (tbUser.getParentid() == null || tbUser.getParentid() == 1) {
                        bindParend(tbUser, parent);
                        tbUserService.update(tbUser);
                    }
                }).start();
                return str.toString();
            }
        }
        return "success";
    }

    /**
     * 绑定上下级关系,
     *
     * @param tbUser
     * @param parent
     */
    private void bindParend(TbUser tbUser, TbUser parent) {
        WeiXinMsgUtil.tuanduifensi(parent.getWxopenid(), String.valueOf(tbUser.getUserId()), tbUser.getUsername());
        tbUser.setParentid(parent.getUserId());
        if (tbUserService.queryById(parent.getParentid()) != null) {
            TbUser user2 = tbUserService.queryById(parent.getParentid());
            WeiXinMsgUtil.tuanduifensi(user2.getWxopenid(), String.valueOf(tbUser.getUserId()), tbUser.getUsername());
            tbUser.setParentid2(user2.getUserId());
            if (tbUserService.queryById(user2.getParentid()) != null) {
                TbUser user3 = tbUserService.queryById(user2.getParentid());
                tbUser.setParentid3(user3.getUserId());
                if (tbUserService.queryById(user3.getParentid()) != null) {
                    TbUser user4 = tbUserService.queryById(user3.getParentid());
                    tbUser.setParentid4(user4.getUserId());
                }
            }
        }
    }
//        response.getWriter().append("Served at: ").append(request.getContextPath());


    /**
     * 获取签名
     *
     * @return
     */
    @AuthIgnoreApi
    @RequestMapping("/getSignature")
    public R getSignature(String url) throws WeixinException, IOException {
        //1、获取AccessToken
        TokenManager tokenManager = weixinProxy.getTicketManager(TicketType.jsapi);
        JSSDKConfigurator jssdk = new JSSDKConfigurator(tokenManager);
        //jssdk.apis(JSSDKAPI.chooseWXPay,JSSDKAPI.getLocation);
        jssdk.apis(JSSDKAPI.chooseWXPay, JSSDKAPI.scanQRCode, JSSDKAPI.onMenuShareTimeline, JSSDKAPI.onMenuShareAppMessage, JSSDKAPI.onMenuShareQQ, JSSDKAPI.onMenuShareWeibo, JSSDKAPI.onMenuShareQZone);

        String jsonData = jssdk.toJSONConfig(url);
        ObjectMapper objectMapper = new ObjectMapper();
        Map map = objectMapper.readValue(jsonData, Map.class);


        return R.ok().put("data", map);
    }




    public static String getAccessToken() {
        String access_token = "";
        String grant_type = "client_credential";//获取access_token填写client_credential
        String AppId = "wx2ae76aac1e31617e";//第三方用户唯一凭证
        String secret = "d2fb2c40bdb842d04da11f7c82fc1fd8";//第三方用户唯一凭证密钥，即appsecret
        //这个url链接地址和参数皆不能变
        String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=" + grant_type + "&appid=" + AppId + "&secret=" + secret;

        try {
            URL urlGet = new URL(url);
            HttpURLConnection http = (HttpURLConnection) urlGet.openConnection();
            http.setRequestMethod("GET"); // 必须是get方式请求
            http.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
            http.setDoOutput(true);
            http.setDoInput(true);
            System.setProperty("sun.net.client.defaultConnectTimeout", "30000");// 连接超时30秒
            System.setProperty("sun.net.client.defaultReadTimeout", "30000"); // 读取超时30秒
            http.connect();
            InputStream is = http.getInputStream();
            int size = is.available();
            byte[] jsonBytes = new byte[size];
            is.read(jsonBytes);
            String message = new String(jsonBytes, "UTF-8");
            JSONObject demoJson = JSONObject.fromObject(message);
            System.out.println("JSON字符串：" + demoJson);
            access_token = demoJson.getString("access_token");
            is.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return access_token;
    }


    public static String getTicket(String access_token) {
        String ticket = null;
        String url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=" + access_token + "&type=jsapi";//这个url链接和参数不能变
        try {
            URL urlGet = new URL(url);
            HttpURLConnection http = (HttpURLConnection) urlGet.openConnection();
            http.setRequestMethod("GET"); // 必须是get方式请求
            http.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
            http.setDoOutput(true);
            http.setDoInput(true);
            System.setProperty("sun.net.client.defaultConnectTimeout", "30000");// 连接超时30秒
            System.setProperty("sun.net.client.defaultReadTimeout", "30000"); // 读取超时30秒
            http.connect();
            InputStream is = http.getInputStream();
            int size = is.available();
            byte[] jsonBytes = new byte[size];
            is.read(jsonBytes);
            String message = new String(jsonBytes, "UTF-8");
            JSONObject demoJson = JSONObject.fromObject(message);
            System.out.println("JSON字符串：" + demoJson);
            ticket = demoJson.getString("ticket");
            is.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ticket;
    }


    public static String SHA1(String decript) {
        try {
            MessageDigest digest = MessageDigest.getInstance("SHA-1");
            digest.update(decript.getBytes());
            byte messageDigest[] = digest.digest();
            // Create Hex String
            StringBuffer hexString = new StringBuffer();
            // 字节数组转换为 十六进制 数
            for (int i = 0; i < messageDigest.length; i++) {
                String shaHex = Integer.toHexString(messageDigest[i] & 0xFF);
                if (shaHex.length() < 2) {
                    hexString.append(0);
                }
                hexString.append(shaHex);
            }
            return hexString.toString();

        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return "";
    }

    public static void main(String[] args) {
        //1、获取AccessToken
        String accessToken = getAccessToken();

        Logger logger = LoggerFactory.getLogger(AdvancedUtil.class);
        SNSUserInfo snsUserInfo = null;
        // 拼接请求地址
        String requestUrl = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN";
        requestUrl = requestUrl.replace("ACCESS_TOKEN", accessToken).replace("OPENID", "osp6SxBvOqRxVBLE3eANWHh1_uYc");
        // 通过网页授权获取用户信息
        JSONObject jsonObject = CommonUtil.httpsRequest(requestUrl, "GET", null);

        if (null != jsonObject) {
            try {
                snsUserInfo = new SNSUserInfo();
                // 用户的标识
                logger.info(jsonObject.getString("openid"));
                snsUserInfo.setOpenId(jsonObject.getString("openid"));
                // 昵称
                logger.info(jsonObject.getString("nickname"));
                snsUserInfo.setNickname(jsonObject.getString("nickname"));
                // 性别（1是男性，2是女性，0是未知）
                logger.info(jsonObject.getString("sex"));
                snsUserInfo.setSex(jsonObject.getInt("sex"));
                // 用户所在国家
                logger.info(jsonObject.getString("country"));
                snsUserInfo.setCountry(jsonObject.getString("country"));
                // 用户所在省份
                logger.info(jsonObject.getString("province"));
                snsUserInfo.setProvince(jsonObject.getString("province"));
                // 用户所在城市
                logger.info(jsonObject.getString("city"));
                snsUserInfo.setCity(jsonObject.getString("city"));
                // 用户头像
                logger.info(jsonObject.getString("headimgurl"));
                snsUserInfo.setHeadImgUrl(jsonObject.getString("headimgurl"));
            } catch (Exception e) {
                snsUserInfo = null;
                int errorCode = jsonObject.getInt("errcode");
                String errorMsg = jsonObject.getString("errmsg");
                logger.info("获取用户信息失败 errcode:{} errmsg:{}", errorCode, errorMsg);
            }
        }
//        System.out.print(accessToken);
//
//        String menu = "{\n" + "    \"button\": [\n" + "        {\n" + "            \"name\": \"进入商城\", \n" + "            \"type\": \"view\", \n" + "            \"url\": \"http://www.guangtouboy.com\"\n" + "        }, \n" + "        {\n" + "            \"name\": \"会员中心\", \n" + "            \"sub_button\": [\n" + "                {\n" + "                    \"type\": \"view\", \n" + "                    \"name\": \"个人中心\", \n" + "                    \"url\": \"http://www.guangtouboy.com/#/Mine\"\n" + "                }, \n" + "                {\n" + "                    \"type\": \"view\", \n" + "                    \"name\": \"我的二维码\", \n" + "                    \"url\": \"http://www.guangtouboy.com/#/MyQRCode\"\n" + "                }, \n" + "                {\n" + "                    \"type\": \"view\", \n" + "                    \"name\": \"商业模式\", \n" + "                    \"url\": \"http://mp.weixin.qq.com/s?__biz=MzI5Nzk0MzIxOA==&mid=100000052&idx=1&sn=a31ebc20876e4d2ce09eac9c405e0fab&chksm=6cac28e95bdba1ff51aa49d5ed9bcf900d7f4d46d9c21e3fe795b8f852d825eec9ef451bc516&scene=18#wechat_redirect\"\n" + "                }\n" + "            ]\n" + "        }, \n" + "        {\n" + "            \"name\": \"光头娃\", \n" + "            \"sub_button\": [\n" + "                {\n" + "                    \"type\": \"view\", \n" + "                    \"name\": \"企业简介\", \n" + "                    \"url\": \"http://mp.weixin.qq.com/s?__biz=MzI5Nzk0MzIxOA==&mid=100000025&idx=1&sn=3eefa392f3e68f053ae778f1035e3c29&chksm=6cac28c45bdba1d29bf093696026c27b4858ba6acedd59c158acb2b0af2b8fa504d282ff29d1&scene=18#wechat_redirect\"\n" + "                }, \n" + "                {\n" + "                    \"type\": \"view\", \n" + "                    \"name\": \"加入我们\", \n" + "                    \"url\": \"http://mp.weixin.qq.com/s?__biz=MzI5Nzk0MzIxOA==&mid=100000027&idx=1&sn=a0f64ceb685c0678422920c99db9818e&chksm=6cac28c65bdba1d09f2e65f533356ffd6718e85da1dc63717f19e1099ad97e5288db9c3649fb&scene=18#wechat_redirect\"\n" + "                }, \n" + "                {\n" + "                    \"type\": \"view\", \n" + "                    \"name\": \"光头娃商学院\", \n" + "                    \"url\": \"http://mp.weixin.qq.com/mp/homepage?__biz=MzI5Nzk0MzIxOA==&hid=1&sn=20a4c23da7d036cb3ed30086bffae4ad&scene=18#wechat_redirect\"\n" + "                }, \n" + "                {\n" + "                    \"type\": \"view\", \n" + "                    \"name\": \"产品H5简介\", \n" + "                    \"url\": \"https://g.eqxiu.com/s/JdoVwkEs?from=sqq\"\n" + "                }\n" + "            ]\n" + "        }\n" + "    ]\n" + "}";
//
//        //2、获取Ticket
//        String jsapi_ticket = getTicket(accessToken);
//
//        //3、时间戳和随机字符串
//        String noncestr = UUID.randomUUID().toString().replace("-", "").substring(0, 16);//随机字符串
//        String timestamp = String.valueOf(System.currentTimeMillis() / 1000);//时间戳
//
//        System.out.println("accessToken:" + accessToken + "\njsapi_ticket:" + jsapi_ticket + "\n时间戳：" + timestamp + "\n随机字符串：" + noncestr);
//
//        //4、获取url
//        String url = "http://www.guangtouboy.com/gtw/login.html";
//
//        //5、将参数排序并拼接字符串
//        String str = "jsapi_ticket=" + jsapi_ticket + "&noncestr=" + noncestr + "&timestamp=" + timestamp + "&url=" + url;
//
//        //6、将字符串进行sha1加密
//        String signature = SHA1(str);
//        System.out.println("参数：" + str + "\n签名：" + signature);
    }
}
